package com.coovane.bytetrix.service.impl.system;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.coovane.bytetrix.common.enumeration.EnabledEnum;
import com.coovane.bytetrix.common.enumeration.ErrorCodeEnum;
import com.coovane.bytetrix.common.exception.DuplicateException;
import com.coovane.bytetrix.common.exception.GenericAssert;
import com.coovane.bytetrix.common.exception.GenericException;
import com.coovane.bytetrix.common.exception.ParamIsNullException;
import com.coovane.bytetrix.common.util.ConvertUtils;
import com.coovane.bytetrix.common.util.Copier;
import com.coovane.bytetrix.dao.system.AdminPositionDao;
import com.coovane.bytetrix.domain.system.AdminPosition;
import com.coovane.bytetrix.common.model.system.AdminPositionDTO;
import com.coovane.bytetrix.common.model.system.AdminPositionListVO;
import com.coovane.bytetrix.common.model.system.AdminPositionQuery;
import com.coovane.bytetrix.service.system.AdminPositionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * <p>
 * 描述：岗位管理Service具体实现逻辑
 * </p >
 *
 * @author: liuchangrong
 * @date: 2022/11/27 20:09
 * @copyright: companyName
 * @see
 * @since 1.8
 */
@Slf4j
@Service
public class AdminPositionServiceImpl extends ServiceImpl<AdminPositionDao, AdminPosition>
        implements AdminPositionService {

    @Override
    public IPage<AdminPositionListVO> pageQuery(AdminPositionQuery query) {
        Page<AdminPosition> page = new Page<>(query.getPage(), query.getLimit());
        LambdaQueryWrapper<AdminPosition> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(query.getPositionCode())) {
            queryWrapper.like(AdminPosition::getPositionCode, query.getPositionCode());
        }
        if (StringUtils.isNotBlank(query.getPositionName())) {
            queryWrapper.like(AdminPosition::getPositionName, query.getPositionName());
        }
        if (Objects.nonNull(query.getEnabled())) {
            queryWrapper.eq(AdminPosition::getEnabled, query.getEnabled());
        }
        Page<AdminPosition> adminPositionPage = this.getBaseMapper().selectPage(page, queryWrapper);
        return adminPositionPage.convert(
                adminPosition -> ConvertUtils.convert(adminPosition, AdminPositionListVO.class));
    }

    @Override
    public AdminPositionDTO getDetail(String id) {
        GenericAssert.notNull(id, new ParamIsNullException(ErrorCodeEnum.PARAM_IS_NULL));
        AdminPosition adminPosition = this.getById(id);
        return ConvertUtils.convert(adminPosition, AdminPositionDTO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String deleteById(String id) {
        GenericAssert.notNull(id, new ParamIsNullException(ErrorCodeEnum.PARAM_IS_NULL));
        boolean removeResult = this.removeById(id);
        GenericAssert.isTrue(removeResult, new GenericException(ErrorCodeEnum.OPERATE_FAILED));
        return id;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String create(AdminPositionDTO dto) {
        GenericAssert.notNull(dto.getPositionCode(), new ParamIsNullException(ErrorCodeEnum.PARAM_IS_NULL, "岗位编码不能为空"));
        GenericAssert.notNull(dto.getPositionName(), new ParamIsNullException(ErrorCodeEnum.PARAM_IS_NULL, "岗位姓名不能为空"));
        // 校验编码和名称是否重复
        assertIfDuplicate(dto);

        // 岗位状态如果为空，则默认开启
        if (Objects.isNull(dto.getEnabled())) {
            dto.setEnabled(EnabledEnum.ENABLED.getCode());
        }
        AdminPosition adminPosition = Copier.copy(dto, new AdminPosition());
        boolean saveResult = this.save(adminPosition);
        GenericAssert.isTrue(saveResult, new GenericException(ErrorCodeEnum.OPERATE_FAILED));
        return adminPosition.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String modify(AdminPositionDTO dto) {
        GenericAssert.notNull(dto.getId(), new ParamIsNullException(ErrorCodeEnum.PARAM_IS_NULL, "岗位唯一标识不能为空"));
        GenericAssert.notNull(dto.getPositionCode(), new ParamIsNullException(ErrorCodeEnum.PARAM_IS_NULL, "岗位编码不能为空"));
        GenericAssert.notNull(dto.getPositionName(), new ParamIsNullException(ErrorCodeEnum.PARAM_IS_NULL, "岗位姓名不能为空"));
        // 校验编码和名称是否重复
        assertIfDuplicate(dto);
        AdminPosition adminPosition = Copier.copy(dto, new AdminPosition());
        boolean updateResult = this.updateById(adminPosition);
        GenericAssert.isTrue(updateResult, new GenericException(ErrorCodeEnum.OPERATE_FAILED));
        return adminPosition.getId();
    }

    @Override
    public void assertIfDuplicate(AdminPositionDTO dto) {
        LambdaQueryWrapper<AdminPosition> wrapper = new LambdaQueryWrapper<>();
        // 更新的时候需要判断非当前数据
        if (StringUtils.isNotBlank(dto.getId())) {
            wrapper.ne(AdminPosition::getId, dto.getId());
        }
        wrapper.eq(AdminPosition::getPositionCode, dto.getPositionCode());
        // 先校验编码是否重复
        boolean exists = this.getBaseMapper().exists(wrapper);
        GenericAssert.isFalse(exists, new DuplicateException(ErrorCodeEnum.PARAM_CODE_DUPLICATE, "岗位编码重复"));

        wrapper.clear();
        // 更新的时候需要判断非当前数据
        if (StringUtils.isNotBlank(dto.getId())) {
            wrapper.ne(AdminPosition::getId, dto.getId());
        }
        wrapper.eq(AdminPosition::getPositionName, dto.getPositionName());
        // 校验名称是否重复
        exists = this.getBaseMapper().exists(wrapper);
        GenericAssert.isFalse(exists, new DuplicateException(ErrorCodeEnum.PARAM_NAME_DUPLICATE, "岗位名称重复"));
    }
}
